Observer pattern

观察者模式定义了对象之间的一对多依赖,观察者依赖于此主体,只要主体状态有变化,观察者就会被通知。

Design_pattern_observer_1

一种基于Subject和Observer接口的实现:

Design_pattern_observer_2

观察者模式提供了一种对象设计,让主题和观察者之间实现松耦合。

气象站的观察者模式设计:

Design_pattern_observer_3

实现代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}

public interface Observer {
public void update(float temp, float humidity, float pressure);
}

public interface DisplayElement {
public void display();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public class WeatherData implements Subject {
private ArrayList observers;
private float temperature;
private float humidity;
private float pressure;

public WeatherData() {
observers = new ArrayList();
}

public void registerObserver(Observer o) {
observers.add(o);
}

public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if (i >= 0) {
observers.remove(i);
}
}

public void notifyObservers() {
for (int i = 0; i < observers.size(); i++) {
Observer observer = (Observer)observers.get(i);
observer.update(temperature, humidity, pressure);
}
}

public void measurementsChanged() {
notifyObservers();
}

public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}

// other WeatherData methods here

public float getTemperature() {
return temperature;
}

public float getHumidity() {
return humidity;
}

public float getPressure() {
return pressure;
}
}

同样,观察者模式也有缺点,观察者无法主动获取所需要的数据,而是由主题对象一次推送所有数据,在某些情况并不合适,后面介绍的模式将解决这个问题。

另外Java内置有观察者模式,但是是基于抽象类,而不是接口的实现,在很多时候并不适用。在JDK中,Swing的JButton等组件加入Listener即是使用了观察者模式,当按扭事件被触发时,所有listener将会得到通知并做出相应行为。